// Copyright (c) Appeon. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. 
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.

namespace SnapObjects.Data
{
    internal class DynamicModelAccessor : IModelAccessor<DynamicModel>
    {
        private readonly DynamicModelFactory _dynamicModelFactory;

        internal DynamicModelAccessor(
            DynamicModelFactory factory)
        {
            _dynamicModelFactory = factory;
        }

        public IModelMeta ModelMeta => _dynamicModelFactory.ModelMeta;

        public object GetValue(DynamicModel model, int index)
        {
            return model.GetValue(index);
        }

        public object GetValue(DynamicModel model, string name)
        {
            return model.GetValue(name);
        }

        public void SetValue(DynamicModel model, int index, object value)
        {
            model.SetValue(index, value);
        }

        public void SetValue(DynamicModel model, string name, object value)
        {
            model.SetValue(name, value);
        }

        public DynamicModel Clone(DynamicModel model)
        {
            return model.Clone();
        }

        public void CopyModel(DynamicModel toModel, DynamicModel fromModel)
        {
            toModel.CopyFrom(fromModel);
        }

        public int IndexOf(string name)
        {
            return this.ModelMeta.IndexOf(name);
        }

        public bool ValueEquals(DynamicModel model1, DynamicModel model2)
        {
            if (model1 == model2)
            {
                return true;
            }

            if (model1.IsCreatedFromSameFactory(model2))
            {
                for (var i = 0; i < model1.PropertyCount; i++)
                {
                    if (ModelHelper.IsValueEquals(model1.GetValue(i), model2.GetValue(i)))
                    {
                        return true;
                    }
                }
            }

            return false;
        }

        public DynamicModel ToModel(
            IModelEntry<DynamicModel> modelEntry,
            bool current = true)
        {
            var model = _dynamicModelFactory.Create();

            foreach (var name in modelEntry.Properties)
            {
                var value = current ? modelEntry.GetCurrentValue(name) :
                                            modelEntry.GetOriginalValue(name);

                this.SetValue(model, name, value);
            }

            return model;
        }

    }
}
